"""
创建蓝图，创建路由和视图函数，接受请求，响应请求
"""

from flask import Blueprint, request, current_app
from common.response_handler import response_ok, response_page_ok, response_error
from common.faker_helper import get_phone_number
from .partner_model import get_city_list_model, get_area_list_model, del_work_order_model, put_work_order_model
from .partner_service import add_work_order_service, get_work_order_service
from common.param_handler import required_param_check, remove_empty_param, param_convert_int, valid_param_filter
from common.param_handler import set_param_default
from .partner_request import req_get_area_list
from common.yaml_handler import yaml_load
import os


partner_bp = Blueprint("parnter", __name__, url_prefix="/partner")


@partner_bp.route("/cities", methods=["GET"])
def get_city_list():
    data = get_city_list_model()
    return response_ok(data)


@partner_bp.route("/areas", methods=["GET"])
def get_area_list():
    # 请求接收原始参数json字典
    json_dict = dict(request.args)
    current_app.logger.info(f"请求接受原始参数: {json_dict}")
    # 过滤保留有效参数
    valid_param_filter(json_dict, ["city_id"])
    # 必填参数校验
    required_param_check(json_dict, ["city_id"])
    # 参数数字类型校验，将其转换为数字
    param_convert_int(json_dict, ["city_id"])
    data = get_area_list_model(json_dict["city_id"])
    return response_ok(data)


@partner_bp.route("/phone", methods=["GET"])
def get_phone():
    return response_ok(get_phone_number())


@partner_bp.route("/order", methods=["POST"])
def add_work_order():
    # 获取请求json传参数据 # form表单传参，可用dict(request.from) 接受数据
    json_dict = request.get_json()
    # 请求接收原始参数json字典
    current_app.logger.info(f"请求接受原始参数: {json_dict}")
    # 过滤保留有效参数
    valid_param_filter(json_dict, [
        "city_id", "area_id", "order_type", "phone_number", "listen_time", "remark"])
    # 必填参数校验
    required_param_check(json_dict, ["city_id", "area_id", "order_type", "phone_number"])
    # 去除值为None或者空字符串""的参数，这些参数在表里均设计有默认值，进行数据入库
    remove_empty_param(json_dict, ["listen_time", "remark"])
    # 参数数字类型校验，将其转换为数字 # PS: 浏览器url输入和前台输入框输入默认为字符串类型
    param_convert_int(json_dict, ["city_id", "area_id", "order_type"])
    current_app.logger.info(f"请求处理后参数: {json_dict}")
    result = add_work_order_service(json_dict)
    return response_ok(result)


@partner_bp.route("/order", methods=["GET"])
def get_work_order():
    json_dict = dict(request.args)
    current_app.logger.info(f"请求接受原始参数: {json_dict}")
    # 过滤保留有效参数
    valid_param_filter(json_dict, [
        "work_order_id", "phone_number", "page_num", "page_size"])
    # 动态条件查询，前台未输入或选择条件则传递空字符串，进行空条件去除
    remove_empty_param(json_dict, ["work_order_id", "phone_number"])
    # 若前台未传递的页码和尺寸参数，则设置相应的默认值
    set_param_default(json_dict, [("page_num", 1), ("page_size", 10)])
    # 参数数字类型校验，将其转换为数字
    param_convert_int(json_dict, ["page_num", "page_size"])
    # phone_number 作为条件字典，默认是等值匹配，我们转换为模糊匹配
    if json_dict.get("phone_number"):
        json_dict["phone_number"] = ("like", json_dict["phone_number"])
    current_app.logger.info(f"请求处理后参数: {json_dict}")
    count, result = get_work_order_service(json_dict)
    return response_page_ok(json_dict["page_num"], json_dict["page_size"], count, result)


@partner_bp.route("/order", methods=["DELETE"])
def del_work_order():
    # 删除工单使用url传参
    json_dict = dict(request.args)
    current_app.logger.info(f"请求接受原始参数: {json_dict}")
    # 过滤保留有效参数
    valid_param_filter(json_dict, ["id"])
    # 必填参数校验
    required_param_check(json_dict, ["id"])
    # 转换数字类型
    param_convert_int(json_dict, ["id"])
    current_app.logger.info(f"请求处理后参数: {json_dict}")
    result = del_work_order_model(json_dict["id"])
    if result:
        # 编辑删除操作，无需返回值，默认为None
        return response_ok()
    else:
        return response_error("工单不存在")


@partner_bp.route("/order", methods=["PUT"])
def put_work_order():
    # 编辑工单使用json传参
    json_dict = request.get_json()
    current_app.logger.info(f"请求接受原始参数: {json_dict}")
    # 过滤保留有效参数
    valid_param_filter(json_dict, ["id", "phone_number", "remark"])
    # 必填参数校验 # PS: 前端设计phone_num或remark发生改变才请求后端更改，所以我们后端设计参数均为必填项
    required_param_check(json_dict, ["id", "phone_number", "remark"])
    # 转换数字类型
    param_convert_int(json_dict, ["id"])
    """
    # view层做非法去除，必填校验，设置默认值，类型和范围校验(如数字区间或者字符串长度等)
    # 但我们这里暂不做细节的类型和范围判断，能用就行 = =, 当前情况
    数字：若传字符串，会转换为数字，若无法转换，给出提示
    字符串: 若传数字，mysql会将数字转换为字符串入表
    日期格式：当前不做后台校验，错误日期格式入表，会给出sql错误提示 Incorrect datetime value
    长度不满足入表条件，则会给出sql错误
    # service层进行数据逻辑校验，如是否是正确的工单类型枚举(0普通1优质)，城市id、区域id是否合法和对应
    # 我们也不做细节判断，能用就行，即工单类型2也会入库，只是前台无法解析类型展示为空
    """
    current_app.logger.info(f"请求处理后参数: {json_dict}")
    result = put_work_order_model(json_dict)
    if result:
        # 编辑删除操作，无需返回值，默认为None
        return response_ok()
    else:
        return response_error("工单不存在")


@partner_bp.route("/request/demo", methods=["GET"])
def request_dev_api_demo():
    """
    我们造数据，大部分场景都是拼装参数后，调用开发接口，此案例就是通过http调用自己的服务接口
    """
    # 拼装请求参数中需要修改的字段
    city_id = 1
    data = req_get_area_list(city_id)
    return response_ok(data)
